<?php
// +----------------------------------------------------------------------
// | HisiPHP框架[基于ThinkPHP5.1开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2016-2021 http://www.hisiphp.com
// +----------------------------------------------------------------------
// | HisiPHP承诺基础框架永久免费开源，您可用于学习和商用，但必须保留软件版权信息。
// +----------------------------------------------------------------------
// | Author: 橘子俊 <364666827@qq.com>，开发者QQ群：50304283
// +----------------------------------------------------------------------
namespace app\common\model;

use think\Model;
use think\Image;
use think\File;

/**
 * 附件模型
 * @package app\common\model
 */
class SystemAnnex extends Model
{
    // 定义时间戳字段名
    protected $createTime = 'ctime';
    protected $updateTime = false;

    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    /**
     * [兼容旧版]附件上传
     * @param string $from 来源
     * @param string $group 附件分组,默认sys[系统]，模块格式：m_模块名，插件：p_插件名
     * @param string $water 水印，参数为空默认调用系统配置，no直接关闭水印，image 图片水印，text文字水印
     * @param string $thumb 缩略图，参数为空默认调用系统配置，no直接关闭缩略图，如需生成 500x500 的缩略图，则 500x500多个规格请用";"隔开
     * @param string $thumb_type 缩略图方式
     * @param string $input 文件表单字段名
     * @author 橘子俊 <364666827@qq.com>
     * @return json
     */
    public static function upload($from = 'input', $group = 'sys', $water = '', $thumb = '', $thumbType = '', $input = 'file')
    {
        $param                  = [];
        $param['from']          = $from;
        $param['group']         = $group;
        $param['water']         = $water;
        $param['thumb']         = $thumb;
        $param['thumb_type']    = $thumbType;
        $param['input']         = $input;

        $params = request()->param();

        if (isset($params['full_path'])) {
            $param['full_path'] = true;
        }

        if (isset($params['driver'])) {
            $param['driver'] = $params['driver'];
        }

        return self::fileUpload($param);

    }

    /**
     * [新]附件上传
     * @param string $from 来源
     * @param string $group 附件分组,默认sys[系统]，模块格式：m_模块名，插件：p_插件名
     * @param string $water 水印，参数为空默认调用系统配置，no直接关闭水印，image 图片水印，text文字水印
     * @param string $thumb 缩略图，参数为空默认调用系统配置，no直接关闭缩略图，如需生成 500x500 的缩略图，则 500x500多个规格请用";"隔开
     * @param string $thumb_type 缩略图方式
     * @param string $input 文件表单字段名
     * @param string $full_path 是否返回完整的文件路径(含域名)本地上传有效
     * @param string $driver 指定上传驱动
     * @author 橘子俊 <364666827@qq.com>
     * @return json
     */
    public static function fileUpload($param = [])
    {

        if (empty($param)) {
            $param = request()->param();
        }

        $from       = isset($param['from']) ? strtolower($param['from']) : 'input';
        $group      = isset($param['group']) ? $param['group'] : 'sys';
        $water      = isset($param['water']) ? $param['water'] : '';
        $thumb      = isset($param['thumb']) && !empty($param['thumb']) ? $param['thumb'] : config('upload.thumb_size');
        $thumbType  = isset($param['thumb_type']) && !empty($param['thumb_type'])  ? $param['thumb_type'] : config('upload.thumb_type');
        $input      = isset($param['input']) ? $param['input'] : 'file';
        $fullPath   = isset($param['full_path']) ? $param['full_path'] : false;
        $driver     = isset($param['driver']) ? $param['driver'] : config('upload.upload_driver');

        if (empty($water)) {
            if (config('upload.image_watermark') == 1) {
                $water = 'image';
            } elseif (config('upload.text_watermark') == 1) {
                $water = 'text';
            }
        }

        switch ($from) {

            case 'kindeditor':

                $input = 'imgFile';

                break;

            case 'umeditor':

                $input = 'upfile';

                break;

            case 'ckeditor':

                $input = 'upload';

                break;

            case 'ueditor':

                $input = 'upfile';

                if (isset($_GET['action']) && $_GET['action'] == 'config') {

                    $content    = file_get_contents('./static/js/editor/ueditor/config.json');
                    $json       = preg_replace("/\/\*[\s\S]+?\*\//", "", $content);

                    echo json_encode(json_decode($json, 1), 1);

                    exit;
                }

                break;

            default:// 默认使用layui.upload上传控件
                break;
        }

        $file = request()->file($input);

        $data = [];
        if (empty($file)) {
            return self::result('未找到上传的文件(文件大小可能超过php.ini默认2M限制)！', $from);
        }

        if ($file->getMime() == 'text/x-php' || $file->getMime() == 'text/html') {
            return self::result('禁止上传php,html文件！', $from);
        }

        // 格式、大小校验
        if ($file->checkExt(config('upload.upload_image_ext'))) {

            $type = 'image';
            if (config('upload.upload_image_size') > 0 && !$file->checkSize(config('upload.upload_image_size')*1024)) {
                return self::result('上传的图片大小超过系统限制['.config('upload.upload_image_size').'KB]！', $from);
            }

        } else if ($file->checkExt(config('upload.upload_file_ext'))) {

            $type = 'file';
            if (config('upload.upload_file_size') > 0 && !$file->checkSize(config('upload.upload_file_size')*1024)) {
                return self::result('上传的文件大小超过系统限制['.config('upload.upload_file_size').'KB]！', $from);
            }

        } else if ($file->checkExt('avi,mkv,mp3,mp4')) {

            $type = 'media';

        } else {

            return self::result('非系统允许的上传格式！', $from);

        }

        if (!empty($driver) && $driver != 'local') {
            $param['file'] = $file;
            $data = runhook('system_annex_upload', $param, true);
            if (!is_array($data)) {
                return self::result($data);
            } elseif (isset($data[0])) {
                // 挂载多个插件的时候，提取有效值
                foreach($data as $v) {
                    if (isset($v['file'])) {
                        $data = ['file' => $v['file']];
                        continue;
                    }
                }
            }
        } else {

            // 文件存放路径
            //$filePath = '/upload/'.$group.'/'.$type.'/';
            $filePath = '/upload/'.$type.'/';

            // 执行上传
            $upfile = $file->rule('uploadDate')->move('.'.$filePath);
            if ( !is_file('.'.$filePath.$upfile->getSaveName()) ) {
                return self::result('文件上传失败！', $from);
            }

            $fileCount  = 1;
            $fileSize   = round($upfile->getInfo('size')/1024, 2);
            $oldfileName=$upfile->getInfo('name');

            $data = [
                'file'      => $filePath.str_replace('\\', '/', $upfile->getSaveName()),
                'hash'      => $upfile->hash(),
                'data_id'   => input('param.data_id', 0),
                'type'      => $type,
                'size'      => $fileSize,
                'group'     => $group,
                'upfileName'=>$oldfileName,
                'ctime'     => request()->time(),
            ];

            $data['thumb'] = [];

            if ($type == 'image') {

                $image = \think\Image::open('.'.$data['file']);

                // 水印
                if (!empty($water) && $water != 'no') {

                    if ($water == 'text') {

                        if (is_file('.'.config('upload.text_watermark_font'))) {

                            $image->text(config('upload.text_watermark_content'), '.'.config('upload.text_watermark_font'), config('upload.text_watermark_size'), config('upload.text_watermark_color'))
                            ->save('.'.$data['file']);

                        }

                    } elseif ($water == 'image') {

                        if (is_file('.'.config('upload.image_watermark_pic'))) {

                            $image->water('.'.config('upload.image_watermark_pic'), config('upload.image_watermark_location'), config('upload.image_watermark_opacity'))
                            ->save('.'.$data['file']);

                        }

                    }

                }

                // 缩略图
                if (!empty($thumb) && $thumb != 'no') {

                    $thumbs = explode(';', $thumb);
                    foreach ($thumbs as $k => $v) {

                        $tSize = explode('x', strtolower($v));

                        if (!isset($tSize[1])) {
                            $tSize[1] = $tSize[0];
                        }

                        $newThumb = $data['file'].'_'.$tSize[0].'x'.$tSize[1].'.'.strtolower(pathinfo($upfile->getInfo('name'), PATHINFO_EXTENSION));

                        $image->thumb($tSize[0], $tSize[1], $thumbType)->save('.'.$newThumb);

                        $thumbSize = round(filesize('.'.$newThumb)/1024, 2);

                        $data['thumb'][$k]['type']      = 'image';
                        $data['thumb'][$k]['group']     = $group;
                        $data['thumb'][$k]['file']      = $newThumb;
                        $data['thumb'][$k]['size']      = $thumbSize;
                        $data['thumb'][$k]['hash']      = hash_file('md5', '.'.$newThumb);
                        $data['thumb'][$k]['ctime']     = request()->time();
                        $data['thumb'][$k]['data_id']   = input('param.data_id', 0);

                        $fileSize+$thumbSize;
                        $fileCount++;

                    }
                }

            }

            // 返回带域名的路径
            if ($fullPath && $driver == 'local') {
            	$data['file'] = trim(env('img_url'), '/') . $data['file'];
            }
        }

        return self::result('文件上传成功。', $from, 1, $data);

    }

    /**
     * @author sparkguo
     * 合成图片
     * @param array  $pic_list [图片列表数组]
     * @param boolean $is_save  [是否保存，true保存，false输出到浏览器]
     * @param string $save_path [保存路径]
     * @return boolean|string
     */
    public function getGroupAvatar($pic_list=array(),$is_save=false,$save_path=''){
        //验证参数
        if(empty($pic_list) || empty($save_path)){
            return false;
        }
        if($is_save){
            //如果需要保存，需要传保存地址
            if(empty($save_path)){
                return false;
            }
        }
        // 只操作前9个图片
        $pic_list = array_slice($pic_list, 0, 9);
        //设置背景图片宽高
        $bg_w = 150; // 背景图片宽度
        $bg_h = 150; // 背景图片高度
        //新建一个真彩色图像作为背景
        $background = imagecreatetruecolor($bg_w,$bg_h);
        //为真彩色画布创建白灰色背景，再设置为透明
        $color = imagecolorallocate($background, 202, 201, 201);
        imagefill($background, 0, 0, $color);
        imageColorTransparent($background, $color);
        //根据图片个数设置图片位置
        $pic_count = count($pic_list);
        $lineArr = array();//需要换行的位置
        $space_x = 3;
        $space_y = 3;
        $line_x = 0;
        switch($pic_count) {
            case 1: // 正中间
                $start_x = intval($bg_w/4); // 开始位置X
                $start_y = intval($bg_h/4); // 开始位置Y
                $pic_w = intval($bg_w/2); // 宽度
                $pic_h = intval($bg_h/2); // 高度
                break;
            case 2: // 中间位置并排
                $start_x = 2;
                $start_y = intval($bg_h/4) + 3;
                $pic_w = intval($bg_w/2) - 5;
                $pic_h = intval($bg_h/2) - 5;
                $space_x = 5;
                break;
            case 3:
                $start_x = 40; // 开始位置X
                $start_y = 5; // 开始位置Y
                $pic_w = intval($bg_w/2) - 5; // 宽度
                $pic_h = intval($bg_h/2) - 5; // 高度
                $lineArr = array(2);
                $line_x = 4;
                break;
            case 4:
                $start_x = 4; // 开始位置X
                $start_y = 5; // 开始位置Y
                $pic_w = intval($bg_w/2) - 5; // 宽度
                $pic_h = intval($bg_h/2) - 5; // 高度
                $lineArr = array(3);
                $line_x = 4;
                break;
            case 5:
                $start_x = 30; // 开始位置X
                $start_y = 30; // 开始位置Y
                $pic_w = intval($bg_w/3) - 5; // 宽度
                $pic_h = intval($bg_h/3) - 5; // 高度
                $lineArr = array(3);
                $line_x = 5;
                break;
            case 6:
                $start_x = 5; // 开始位置X
                $start_y = 30; // 开始位置Y
                $pic_w = intval($bg_w/3) - 5; // 宽度
                $pic_h = intval($bg_h/3) - 5; // 高度
                $lineArr = array(4);
                $line_x = 5;
                break;
            case 7:
                $start_x = 53; // 开始位置X
                $start_y = 5; // 开始位置Y
                $pic_w = intval($bg_w/3) - 5; // 宽度
                $pic_h = intval($bg_h/3) - 5; // 高度
                $lineArr = array(2,5);
                $line_x = 5;
                break;
            case 8:
                $start_x = 30; // 开始位置X
                $start_y = 5; // 开始位置Y
                $pic_w = intval($bg_w/3) - 5; // 宽度
                $pic_h = intval($bg_h/3) - 5; // 高度
                $lineArr = array(3,6);
                $line_x = 5;
                break;
            case 9:
                $start_x = 5; // 开始位置X
                $start_y = 5; // 开始位置Y
                $pic_w = intval($bg_w/3) - 5; // 宽度
                $pic_h = intval($bg_h/3) - 5; // 高度
                $lineArr = array(4,7);
                $line_x = 5;
                break;
        }
        foreach( $pic_list as $k=>$pic_path ) {
            $kk = $k + 1;
            if ( in_array($kk, $lineArr) ) {
                $start_x = $line_x;
                $start_y = $start_y + $pic_h + $space_y;
            }
            //获取图片文件扩展类型和mime类型，判断是否是正常图片文件
            //非正常图片文件，相应位置空着，跳过处理
            $image_mime_info = @getimagesize($pic_path);
            if($image_mime_info && !empty($image_mime_info['mime'])){
                $mime_arr = explode('/',$image_mime_info['mime']);
                if(is_array($mime_arr) && $mime_arr[0] == 'image' && !empty($mime_arr[1])){
                    switch($mime_arr[1]) {
                        case 'jpg':
                        case 'jpeg':
                            $imagecreatefromjpeg = 'imagecreatefromjpeg';
                            break;
                        case 'png':
                            $imagecreatefromjpeg = 'imagecreatefrompng';
                            break;
                        case 'gif':
                        default:
                            $imagecreatefromjpeg = 'imagecreatefromstring';
                            $pic_path = file_get_contents($pic_path);
                            break;
                    }
                    //创建一个新图像
                    $resource = $imagecreatefromjpeg($pic_path);
                    //将图像中的一块矩形区域拷贝到另一个背景图像中
                    // $start_x,$start_y 放置在背景中的起始位置
                    // 0,0 裁剪的源头像的起点位置
                    // $pic_w,$pic_h copy后的高度和宽度
                    imagecopyresized($background,$resource,$start_x,$start_y,0,0,$pic_w,$pic_h,imagesx($resource),imagesy($resource));
                }
            }
            // 最后两个参数为原始图片宽度和高度，倒数两个参数为copy时的图片宽度和高度
            $start_x = $start_x + $pic_w + $space_x;
        }
        if($is_save){
            $dir = pathinfo($save_path,PATHINFO_DIRNAME);
            if(!is_dir($dir)){
                $file_create_res = mkdir($dir,0777,true);
                if(!$file_create_res){
                    return false;//没有创建成功
                }
            }
            $res = imagejpeg($background,$save_path);
            imagedestroy($background);
            if($res){
                return true;
            }else{
                return false;
            }
        }else{
            //直接输出
            header("Content-type: image/jpg");
            imagejpeg($background);
            imagedestroy($background);
        }
    }

    /**
     * favicon 图标上传
     * @return json
     */
    public static function favicon()
    {

        $file = request()->file('file');

        if (!$file->checkExt('ico')) {
            return self::result('只允许上传ico格式');
        }

        $file->move('./', 'favicon.ico');

        $data['file'] = '/favicon.ico';

        return self::result('文件上传成功。', 'input', 1, $data);
    }

    /**
     * 返回结果
     * @author 橘子俊 <364666827@qq.com>
     * @return array|string
     */
    private static function result($info = '', $from = 'input', $status = 0, $data = [])
    {
        $arr = [];

        switch ($from) {

            case 'kindeditor':

                if ($status == 0) {

                    $arr['error'] = 1;
                    $arr['message'] = $info;

                } else {

                    $arr['error'] = 0;
                    $arr['url'] = $data['file'];

                }

                break;

            case 'ckeditor':

                if ($status == 1) {
                    echo '<script type="text/javascript">window.parent.CKEDITOR.tools.callFunction(1, "'.$data['file'].'", "");</script>';
                } else {
                    echo '<script type="text/javascript">window.parent.CKEDITOR.tools.callFunction(1, "", "'.$info.'");</script>';
                }

                exit;

                break;

            case 'umeditor':
            case 'ueditor':

                if ($status == 0) {

                    $arr['message'] = $info;
                    $arr['state']   = 'ERROR';

                } else {

                    $arr['message'] = $info;
                    $arr['url']     = $data['file'];
                    $arr['state']   = 'SUCCESS';

                }

                echo json_encode($arr, 1);
                exit;

                break;

            default:

                $arr['msg']     = $info;
                $arr['code']    = $status;
                $arr['data']    = $data;

                break;
        }

        return $arr;

    }

}
